const express = require('express');
const mysql = require('mysql');
const fs = require('fs');
// const bodyParser = require('body-parser');
const app = express();
var tokenList = []
app.use('/public', express.static('public'));
// app.get('/', function (req, res) {
//   res.redirect('/public/index.html')
// });
app.use(function (req,res,next) {
  console.log(req.path)
  res.header('Access-Control-Allow-Origin', '*')
  res.header('Access-Control-Allow-Headers', '*')
  var index = tokenList.indexOf(req.headers.token)
  if(req.path !== '/login' && index===-1){
    return res.send({code:403,msg:'token错误'})
  }
  if(req.path !== '/login' && index!==-1){
    var date = getToken(req.headers.token).date
    if((Date.now()-date)>86400000*2){
      return res.send({code:403,msg:'token过期'})
    }
  }
  next()
})
// app.use(bodyParser.json({limit: '1mb'}));
// app.use(bodyParser.urlencoded({extended: true}));

var connection
// connection.end()
// mysql 8小时无程序执行，自动断开连接
function connect(){
  connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'library'
  });
  connection.connect();
  connection.on('error',function(err){
    if (err.code === 'PROTOCOL_CONNECTION_LOST') {
      connect();
    }
  });
}
connect()

function getTime() {
  var date = new Date()
  var year = date.getFullYear()
  var month = date.getMonth() + 1
  var day = date.getDate()
  var h = date.getHours()
  var m = date.getMinutes()
  var s = date.getSeconds()
  month < 10 && (month = '0' + month)
  day < 10 && (day = '0' + day)
  h < 10 && (h = '0' + h)
  m < 10 && (m = '0' + m)
  s < 10 && (s = '0' + s)
  return `${year}-${month}-${day} ${h}:${m}:${s}`
}
function setToken(id,type){
  var date = new Date()
  var year = date.getFullYear() + ''
  var month = date.getMonth() + 1
  var day = date.getDate()
  month < 10 && (month = '0' + month)
  day < 10 && (day = '0' + day)
  year = year.slice(2)
  var token = `${id}-${type}-${year}${month}${day}`
  return Buffer.from(token).toString('base64')
}
function getToken(token){
  token = Buffer.from(token, 'base64').toString()
  token = token.split('-')
  return {
    id: token[0],
    type:token[1],
    date: new Date(`20${token[2].slice(0,2)}-${token[2].slice(2,4)}-${token[2].slice(4)}`).getTime()
  }
}
app.get('/create', function (req, res) {
  var obj = req.query;
  obj.date = getTime();
  connection.query('INSERT INTO books(name,author,price,publisher,introduction,cover,date,total) VALUES(?,?,?,?,?,?,?,?)',[obj.name,obj.author,obj.price,obj.publisher,obj.introduction,obj.cover,obj.date,obj.total],function (err, rows) {
    res.send(rows)
  })
});
app.get('/deleteBook', function (req, res) {
  var id = req.query.id;
  connection.query(`DELETE FROM books where id=${id}`,function (err, rows) {
    res.send(rows)
  })
});
app.get('/update', function (req, res) {
  var obj = req.query;
  obj.date = getTime();
  connection.query(`UPDATE books SET name = ?,author = ?,price = ?,publisher = ?,introduction = ?,cover = ?,date = ?,total = ? WHERE Id = ?`,[obj.name,obj.author,obj.price,obj.publisher,obj.introduction,obj.cover,obj.date,obj.total,obj.id],function (err, rows) {
    res.send(rows)
  })
});
app.get('/search', function (req, res) {
  var query = req.query;
  var count = 2
  var obj = {}
  var sql = ''
  if(query.name&&query.author){
    sql=` where name="${query.name}" and author="${query.author}"`
  }else if(query.name){
    sql=` where name="${query.name}"`
  }else if(query.author){
    sql=` where author="${query.author}"`
  }
  connection.query(`select * from books${sql} order by id desc limit ${(query.current-1)*query.pageSize},${query.pageSize}`, function (err, rows) {
    count--
    obj.data = rows
    !count && res.send(obj)
  });
  connection.query(`select count(*) as total from books${sql}`, function (err, rows) {
    count--
    obj.total = rows[0].total
    !count && res.send(obj)
  });
});
app.get('/getUser', function (req, res) {
  var query = req.query;
  var count = 2
  var obj = {}
  var sql = ''
  if(query.username){
    sql=` where username="${query.username}"`
  }
  connection.query(`select id,username,type,avatar,nickname from user${sql} order by id desc limit ${(query.current-1)*query.pageSize},${query.pageSize}`, function (err, rows) {
    count--
    obj.data = rows
    !count && res.send(obj)
  });
  connection.query(`select count(*) as total from user${sql}`, function (err, rows) {
    count--
    obj.total = rows[0].total
    !count && res.send(obj)
  });
});
app.get('/updateUser', function (req, res) {
  var obj = req.query;
  var token = getToken(req.headers.token).id
  connection.query(`UPDATE user SET avatar = ?,nickname = ?,password = ? WHERE Id = ?`,[obj.avatar,obj.nickname,obj.password,token],function (err, rows) {
    connection.query(`UPDATE comment SET avatar = ?,nickname = ? WHERE userId = ?`,[obj.avatar,obj.nickname,token],function (err, rows) {
      res.send(rows)
    })
  })
});
app.get('/login', function (req, res) {
  var obj = req.query;
  var token = ''
  connection.query(`select * from user where username="${obj.username}"`, function (err, rows) {
    if(!rows.length){
      if(!(/^1[3456789]\d{9}$/.test(obj.username))){
        return res.send({code:1,msg: '请用手机号登录'})
      }
      obj.date = getTime();
      connection.query('INSERT INTO user(username,password,type,avatar,nickname,date) VALUES(?,?,?,?,?,?)',[obj.username,obj.password,'1','default.png','小太阳',obj.date],function (err, rows) {
        token = setToken(rows.insertId,'1')
        tokenList.push(token)
        res.send({code:0,msg: '注册成功',token,id:rows.insertId,type:'1',nickname:'小太阳',username:obj.username,avatar:'default.png'})
      })
      return
    }
    rows = rows[0]
    if(rows.password!==obj.password){
      return res.send({code:1,msg: '密码错误'})
    }
    token = setToken(rows.id,rows.type)
    tokenList.push(token)
    res.send({code:0,msg: '登录成功',token,id:rows.id,type:rows.type,nickname:rows.nickname,username:rows.username,avatar:rows.avatar})
  });
});
app.get('/getRecord', function (req, res) {
  var query = req.query;
  var count = 2
  var obj = {}
  var sql = ''
  if(query.book&&query.user){
    sql=` where book="${query.book}" and user="${query.user}"`
  }else if(query.book){
    sql=` where book="${query.book}"`
  }else if(query.user){
    sql=` where user="${query.user}"`
  }
  connection.query(`select * from record${sql} order by id desc limit ${(query.current-1)*query.pageSize},${query.pageSize}`, function (err, rows) {
    count--
    obj.data = rows
    !count && res.send(obj)
  });
  connection.query(`select count(*) as total from record${sql}`, function (err, rows) {
    count--
    obj.total = rows[0].total
    !count && res.send(obj)
  });
});
app.get('/getRecordId', function (req, res) {
  var query = req.query;
  var obj = {}
  connection.query(`select bookId from record where user="${query.user}" and type=1`, function (err, rows) {
    obj.data = rows.map(v=>v.bookId)
    obj.total = rows.length
    res.send(obj)
  });
});
app.get('/getComment', function (req, res) {
  var query = req.query;
  var count = 2
  var obj = {}
  connection.query(`select * from comment order by id desc limit ${(query.current-1)*query.pageSize},${query.pageSize}`, function (err, rows) {
    count--
    obj.data = rows
    !count && res.send(obj)
  });
  connection.query(`select count(*) as total from comment`, function (err, rows) {
    count--
    obj.total = rows[0].total
    !count && res.send(obj)
  });
});
app.get('/addComment', function (req, res) {
  var obj = req.query;
  obj.date = getTime();
  obj.userId = getToken(req.headers.token).id;
  connection.query('INSERT INTO comment(userId,avatar,nickname,content,date) VALUES(?,?,?,?,?)',[obj.userId,obj.avatar,obj.nickname,obj.content,obj.date],function (err, rows) {
    res.send(rows)
  })
});
app.get('/deleteComment', function (req, res) {
  var id = req.query.id;
  connection.query(`DELETE FROM comment where id=${id}`,function (err, rows) {
    res.send(rows)
  })
});
app.get('/updateRecord', function (req, res) {
  var obj = req.query;
  connection.query(`select stock from books where id=${obj.bookId}`,function (err, rows) {
    var stock = +rows[0].stock + 1
    console.log(stock)
    connection.query(`UPDATE books SET stock=${stock} WHERE id = ${obj.bookId}`,function (err, rows) {
      connection.query(`UPDATE record SET type = 0,updateTime = ? WHERE Id = ?`,[getTime(),obj.id],function (err, rows) {
        res.send(rows)
      })
    })
  })
  
});
app.get('/addRecord', function (req, res) {
  var obj = req.query;
  var token = getToken(req.headers.token)
  connection.query(`select stock from books where id=${obj.bookId}`,function (err, rows) {
    var stock = rows[0].stock - 1
    connection.query(`UPDATE books SET stock=${stock} WHERE id = ${obj.bookId}`,function (err, rows) {
      connection.query('INSERT INTO record(book,user,bookId,userId,type,createTime) VALUES(?,?,?,?,?,?)',[obj.book,obj.user,obj.bookId,token.id,'1',getTime()],function (err, rows) {
        res.send(rows)
      })
    })
  })
  
});
app.post('/upload', function (req, res) {
  //新建一个空数组接受流的信息
  var chunks = [];
  //获取长度
  let num = 0;
  req.on("data", function (chunk) {
    chunks.push(chunk);
    num += chunk.length;
  });
  req.on("end", function () {
    //最终流的内容本体
    var buffer = Buffer.concat(chunks, num);
    //新建数组接收出去\r\n的数据下标
    let rems = [];
    //根据\r\n分离数据和报头
    for (var i = 0; i < buffer.length; i++) {
      let v = buffer[i];
      let v2 = buffer[i + 1];
      // 10代表\n 13代表\r
      if (v === 13 && v2 === 10) {
        rems.push(i)
      }
    }
    //获取上传图片信息
    let picmsg_1 = buffer.slice(rems[0] + 2, rems[1]).toString();
    let filename = picmsg_1.match(/filename=".*"/g)[0].split('"')[1];
    console.log(filename);
    //图片数据
    var nbuf = buffer.slice(rems[3] + 2, rems[rems.length - 2]);
    let address = Date.now() + filename.slice(filename.indexOf('.'));
    //创建空文件并写入内容
    fs.writeFile('./public/pic/' + address, nbuf, function (err) {
      if (err) {
        console.log(err);
      } else {
        console.log("success")
      }
    });
    res.send({name: filename, path: address})
  });
});

app.listen(88);
